import {ReflectUtils} from '../../reflect/ReflectUtils';
import {Component} from '../Component';
import {ClassMetadata, PropertyMetadata} from '../meta';
import {DecoratorMetadata} from '../meta/DecoratorMetadata';
import {ClassType} from '../../type';
import {Autowired} from '../Autowired';
import {BeanError} from '../../error/BeanError';
import {MethodMeta, ParameterMeta, PropertyMeta} from '../../reflect/Meta';


/**
 * 创建类装饰器
 *
 * @param handler (target: 被修饰的类)
 */
export function createClassDecorator(handler: (target: ClassType<any>) => DecoratorMetadata): ClassDecorator {
  return target => {
    const decoratorMeta = handler(target as any);
    const classMeta: ClassMetadata<any> = {
      metadataType: 'class',
      clazz: target,
      className: target.name,
      options: decoratorMeta,
    };

    ReflectUtils.addClassDecorator(decoratorMeta, target);
    ReflectUtils.addDecoratorTarget(classMeta, Component);
  };
}


/**
 * 创建属性装饰器
 *
 * @param handler (target: 属性所属类, propery: 属性名, type: 属性类型)
 */
export function createPropertyDecorator(
  handler: (target: ClassType<any>, meta: PropertyMeta) => DecoratorMetadata)
  : PropertyDecorator {
  return (target: Object, propertyKey: string) => {
    const propertyClass = Reflect.getMetadata('design:type', target, propertyKey);
    if (!propertyClass) {
      throw new BeanError(`未知属性类型：${target.constructor.name}.${propertyKey}, type : ${propertyClass && propertyClass.name}`);
    }
    if (propertyClass === Object) {
      throw new BeanError(`请明确设置属性类型：${target.constructor.name}.${propertyKey}， type: '${propertyClass.name}'`);
    }

    const decoratorMeta = handler(target.constructor as any, {name: propertyKey, type: propertyClass});
    ReflectUtils.addMetadata('summer:property:decorator', decoratorMeta, target.constructor, propertyKey);

    const propertyMeta: PropertyMetadata<any> = {
      metadataType: 'property',
      name: propertyKey,
      type: propertyClass,
      options: decoratorMeta,
      classMetadata: {
        metadataType: 'class',
        clazz: target.constructor,
        className: target.constructor.name,
      },
    };
    ReflectUtils.addDecoratorTarget(propertyMeta, Autowired);
  };
}


/**
 * 创建方法装饰器
 *
 * @param handler (target: 方法所属类, meta: 方法)
 */
export function createMethodDecorator(
  handler: (target: ClassType<any>, meta: MethodMeta) => DecoratorMetadata)
  : MethodDecorator {
  return (target, propertyKey, descriptor) => {

  };
}

/**
 * 创建参数装饰器你
 *
 * @param handler (target: 参数所在类, meta: 参数信息)
 */
export function createParameterDecorator(
  handler: (target: ClassType<any>, meta: ParameterMeta) => DecoratorMetadata)
  : ParameterDecorator {
  return (target, propertyKey, parameterIndex) => {

  };
}
